home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Disc to the Future 2
/
Disc to the Future Part II Programmer's Reference (Wayzata Technology)(6013)(1992).bin
/
MAC
/
THINKC
/
4_0
/
DIZZY
/
SRC
/
ZAPPER.C
< prev
Wrap
Text File
|
1990-12-29
|
6KB
|
227 lines
/*
>> Dizzy 1.0 Zapper.c
>>
>> A digital circuit simulator & design program for the X Window System
>>
>> Copyright 1990 Juri Munkki, all rights reserved
>>
>> Please read the included file called "DizzyDoc" for information on
>> what your rights are concerning this product.
*/
#include "dizzy.h"
extern Element *LastElem; /* From Arrow.c */
extern int ElemCount; /* Also from Arrow.c */
/*
>> The zapper tool allows the user to delete line segments and
>> elements. If the mouse button is held down, the user can
>> browse through the possible objects by moving the mouse.
>> An object is only deleted after the mouse button is released.
*/
void DoZapperTool()
{
Element *elem,*found,*brother;
int foundpin;
long offs,elemsize;
int i,j,downflag;
Input *ip;
Point MousePoint,oldspot;
Rect selector;
int typefound;
int x1,y1,x2,y2;
ClipEditArea();
PenSize(5,5);
PenXor();
#ifdef MACINTOSH
SetCursor(*GetCursor(129));
#endif
/* Prepare the data so that it can be searched backwards. */
elemsize=0;
ElemCount=0;
for(offs=CurHeader->First;offs<CurHeader->Last;offs+=elem->Length)
{ elem=(Element *)(SimBase+offs);
elem->PrevLength=elemsize;
elemsize=elem->Length;
ElemCount++;
}
LastElem=elem;
typefound=0;
found=0;
GetMouseDownPoint(&MousePoint);
oldspot.h= MousePoint.h+9999; /* Some improbable point */
oldspot.v= MousePoint.v+9999; /* to simulate motion. */
do
{ downflag=GetMouseTrackEvent(&MousePoint);
/* Did mouse move? */
if(MousePoint.h!=oldspot.h || MousePoint.v!=oldspot.v)
{ if(typefound) /* Was there a previous hilite to unhilite? */
{ HILITEMODE;
if(typefound>0)
{ MoveTo(selector.left,selector.top);
LineTo(selector.right,selector.bottom);
}
else
InvertRect(&selector);
}
typefound=0; /* Current hilite==nil */
found=0;
if(PtInRect(MousePoint,&EditClipper)) /* Mouse in edit area? */
{ i=ElemCount;
elem=LastElem;
while(i-- && !found) /* Search for a hit in body area. */
{ if(PtInRect(MousePoint,&elem->Body))
{ found=elem;
typefound= -1; /* An element body was found. */
selector=elem->Body;
HILITEMODE; /* Hilite the found element. */
InvertRect(&selector);
}
elem=(Element *)(((char *) elem)-elem->PrevLength);
}
if(!typefound) /* No element body was found? */
{ i=ElemCount; /* Look for a line instead. */
elem=LastElem;
while(i-- && !typefound)
{ ip=(Input *)&elem->Out[elem->Outputs];
for(j=0;j<elem->Inputs;j++)
{ if(GetConnectLine(ip,elem,j,&x1,&y1,&x2,&y2))
if(PntOnLine(x1,y1,
x2,y2,
MousePoint.h,MousePoint.v)==2)
{ typefound=1; /* A line was found. */
found=elem;
foundpin=j;
selector.left=x1-LCENTERING;
selector.top=y1-LCENTERING;
selector.right=x2-LCENTERING;
selector.bottom=y2-LCENTERING;
HILITEMODE; /* Hilite the found line. */
MoveTo(selector.left,selector.top);
LineTo(selector.right,selector.bottom);
j=elem->Inputs; /* Fall out of ip-loop. */
i=0;
}
ip++;
}
elem=(Element *)(((char *) elem)-elem->PrevLength);
}
}
}
}
oldspot=MousePoint;
} while(downflag);
if(typefound) /* Did we find something? */
{ if(typefound>0) /* Was it a line segment? */
{ HILITEMODE; /* Disconnect line segment. */
MoveTo(selector.left,selector.top);
LineTo(selector.right,selector.bottom);
ip=(Input *)&found->Out[found->Outputs];
ip[foundpin].Chip=0;
ip[foundpin].Pin=0;
InvalLine(selector.left,selector.top,selector.right,selector.bottom);
}
else /* It was an element. */
{ long ouroffset;
int inptcount,outpcount;
Input ip2;
if(found->Type==CONN) /* Unsplit lines */
{ ip2= *(Input *)&found->Out[1];
}
else
{ ip2.Chip=0; /* Disconnect lines. */
ip2.Pin=0;
}
/* First, let's invalidate the display. */
if(found->Type==OUTP || found->Type==INPT)
{ SetTrashRect(&EditClipper);
}
else
{ SetTrashRect(&found->Body);
}
/* Find lines connected to inputs of this chip. Easy. */
ouroffset=((char *)found)-SimBase; /* Our "signature". */
ip = (Input *)&found->Out[found->Outputs];
for(j=0;j<found->Inputs;j++)
{ if(ip->Chip != ouroffset)
if(GetConnectLine(ip,found,j,&x1,&y1,&x2,&y2))
{ ExpandTrash(x2,y2);
}
ip++;
}
/* Find lines connected to outputs of this chip. Harder. */
for(offs=CurHeader->First;offs<CurHeader->Last;offs+=elem->Length)
{ elem=(Element *)(SimBase+offs);
ip=(Input *)&elem->Out[elem->Outputs];
for(j=0;j<elem->Inputs;j++)
{ if(ip->Chip == ouroffset)
{ GetConnectLine(ip,elem,j,&x2,&y2,&x1,&y1);
ExpandTrash(x2,y2);
}
ip++;
}
}
InvalTrash(); /* Invalidate the whole area. */
inptcount=0; /* Number of inputs so far. */
outpcount=0; /* Number of outputs so far. */
/* Disconnect everything from the dead chip. */
for(offs=CurHeader->First;offs<CurHeader->Last;offs+=elem->Length)
{ elem=(Element *)(SimBase+offs);
if(elem->Type==INPT)
elem->PrivData= ++inptcount;
else
if(elem->Type==OUTP)
elem->PrivData= ++outpcount;
ip=(Input *)&elem->Out[elem->Outputs];
for(j=0;j<elem->Inputs;j++)
{ if(ip->Chip==ouroffset)
{ *ip=ip2;
}
ip++;
}
}
HILITEMODE;
InvertRect(&selector);
found->Type=ZAPP; /* Food for garbage collector. */
found->Flags=0;
found->Body=NilRect;
found->InRect=NilRect;
found->OutRect=NilRect;
found->Inputs=0;
found->Outputs=0;
if(CountElementType(ZAPP)>MAX_ZAPS)
{ DatabaseCleanup(); /* Time to garbage collect. */
}
}
}
#ifdef MACINTOSH
InitCursor();
#endif
PenSize(1,1);
PenCopy();
RestoreClipping();
}